#include "stdafx.h"
#pragma once

[export]
enum MergeTokenType
{
	Nonregion = 0,
	Region    = 1,
	RegionName = 2
};
struct MergeToken
{
	MergeToken(MergeTokenType tokenType, std::string text) : Text(text), TokenType(tokenType)
	{
	}
	std::string Text;
	MergeTokenType TokenType;

};

class VectorBuilder
{
private:
	typedef std::vector<MergeToken> container_t ;
	typedef container_t::iterator iterator_t;
	static container_t tokens;
public:
	static void Clear()
	{
		tokens.clear();
	}
	static void AddToken(MergeTokenType type, std::string text)
	{
		MergeToken token(type, text);
		tokens.push_back(token);
	}
	static iterator_t begin()
	{
		return tokens.begin();
	}
	static iterator_t end()
	{
		return tokens.end();
	}
};

std::vector<MergeToken> VectorBuilder::tokens;

namespace
{

	void parse_regionname(char const* str, char const* end)
	{
		string text(str, end);
		/*cout << "region name: ";
		cout << text << endl;*/
		VectorBuilder::AddToken(RegionName, text);
	}
	void parse_regioncontent(char const* str, char const* end)
	{
		string text(str, end);
		/*cout << "region content: ";
		cout << text << endl;*/
		VectorBuilder::AddToken(Region, text);
	}
	void parse_nonregion(char const* str, char const* end)
	{
		string text(str, end);
		/*cout << "nonregion: ";
		cout << text << endl;*/
		VectorBuilder::AddToken(Nonregion, text);
	}
}

//struct mergeparser_closure : boost::spirit::closure<mergeparser_closure, std::vector<string> >
//{
//    member1 tokens;
//
//};

struct push_back_impl
{
    template <typename Container, typename Item>
    struct result
    {
        typedef void type;
    };

    template <typename Container, typename Item>
    void operator()(Container& c, Item const& item) const
    {
        c.push_back(item);
    }
};
function<push_back_impl> const push_back = push_back_impl();
struct mergeparser_closure : boost::spirit::closure<mergeparser_closure, string>
{
	member1 name;
};
struct MergeParserGrammar : public grammar<MergeParserGrammar, mergeparser_closure::context_t>
{

    template <typename ScannerT>
    struct definition
    {
        
        definition(MergeParserGrammar const& self)  
		{ 

			term = print_p | space_p;
			// *region_content[&parse_regioncontent]
			region = (region_open >> *(+(term - region_close))[&parse_regioncontent] >> region_close);// >> *(region_content - region_close)[&parse_regioncontent] >> region_close;
			region_open_noaction = *blank_p >> str_p("//") >> *blank_p >> as_lower_d["#region "] >> *blank_p >> region_name;
			region_open  = *blank_p >> str_p("//") >> *blank_p >> as_lower_d["#region "] >> *blank_p >> region_name[&parse_regionname];
			region_close = *blank_p >> str_p("//") >> *blank_p >> as_lower_d["#endregion "] >> f_str_p(region.name) >> *space_p;
			region_content = region | ((+term) - region_close);
			region_name =  (+(alnum_p | blank_p))[region.name = construct_<string>(arg1, arg2)] || *blank_p;
			
			nonregion = +(term - (region_open_noaction));
			content = (region | nonregion[&parse_nonregion]);
			top = content >> *content >> *space_p;
		}

		typedef rule<ScannerT> rule_t;
		typedef rule<ScannerT, mergeparser_closure::context_t> closure_t;
		rule<ScannerT>  top;
		
		rule_t	term,
				region_close,
				region_name,
				region_content,
				nonregion,
				content;
		
		rule_t region_open,
			   region_open_noaction;

		closure_t region;

        rule<ScannerT> const& start() const { return top; }
    };
};